"""
多窗口管理器
用于管理多个股票图表窗口，解决QApplication实例问题
"""

from .config import config, flags, logger
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTabWidget, QMessageBox
import pyqtgraph as pg
from typing import List, Dict, Optional

from .data_loader import DataLoader
from .candlestick_chart import CandlestickChart
from .volume_chart import VolumeChart
from .mouse_interaction import MouseInteraction, MouseInteractionManager


from .moving_average import MovingAverageManager
from .quota.ma_slope_peaks import MovingAverageSlopePeaksManager


class SingleStockWidget(QWidget):
    """单个股票图表控件"""
    
    def __init__(self, stock_name: str, file_path: str):
        super().__init__()
        self.stock_name = stock_name
        self.file_path = file_path
        
        # 初始化组件
        self.data_loader = DataLoader()
        self.mouse_manager = MouseInteractionManager()
        
        # 图表控件
        self.kline_plot: Optional[pg.PlotWidget] = None
        self.volume_plot: Optional[pg.PlotWidget] = None
        self.kline_chart: Optional[CandlestickChart] = None
        self.moving_average_manager: Optional[MovingAverageManager] = None
        self.moving_average_slope_peaks_manager: Optional[MovingAverageSlopePeaksManager] = None
        self.volume_chart: Optional[VolumeChart] = None
        
        self._setup_ui()
        self._load_data()
    
    def _setup_ui(self):
        """设置UI"""
        logger.debug(f"设置UI: {self.stock_name}")
        layout = QVBoxLayout()
        self.setLayout(layout)
        
        # 创建图形布局
        graphics_layout = pg.GraphicsLayoutWidget()
        layout.addWidget(graphics_layout)
        
        # 创建K线图和成交量图
        self.kline_plot = graphics_layout.addPlot(title=f"{self.stock_name} - K线图", row=0, col=0) # , rowspan = 2

        self.volume_plot = graphics_layout.addPlot(title=f"{self.stock_name} - 成交量", row=1, col=0)

        # 设置行高比例：第0行(上面的K线图) 占3份，第1行(下面的成交量) 占1份

        graphics_layout.ci.layout.setRowStretchFactor(0, 3)  # K线图行高占3份
        graphics_layout.ci.layout.setRowStretchFactor(1, 1)  # 成交量行高占1份

        # 初始化图表
        self.kline_chart = CandlestickChart(self.kline_plot)
        self.moving_average_manager = MovingAverageManager(self.kline_plot)
        self.moving_average_slope_peaks_manager = MovingAverageSlopePeaksManager(self.kline_plot)
        logger.debug(f"初始化移动平均线斜率峰值管理器: {self.stock_name}")
        self.volume_chart = VolumeChart(self.volume_plot)
        
        self.kline_plot.setXLink(self.volume_plot)
        
    def _load_data(self):
        """加载数据"""
        try:
            # 加载数据
            self.data_loader.load_from_csv(self.file_path, config.DEFAULT_DATE_FORMAT)
            
            # 更新图表
            self._update_charts()
            
            # 设置鼠标交互
            self._setup_mouse_interactions()
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"加载 {self.stock_name} 数据失败:\n{str(e)}")
    
    def _update_charts(self):
        """更新图表数据"""

        logger.debug(f"更新图表数据: {self.stock_name}")
        # 获取K线数据
        candlestick_data = self.data_loader.get_candlestick_data()
        self.kline_chart.update_data(candlestick_data)
    
    # 获取成交量数据
        volume_x, volume_heights, volume_colors = self.data_loader.get_volume_data()
        self.volume_chart.update_data(volume_x, volume_heights, volume_colors)

        # 设置移动平均线数据
        self.moving_average_manager.set_data(self.data_loader.get_data())
        self.moving_average_manager.update_moving_averages(config.DEFAULT_MA_PERIODS, config.MA_COLORS)

        # 设置移动平均线斜率峰值数据 拐点
        self.moving_average_slope_peaks_manager.set_data(self.data_loader.get_data())
        logger.debug(f"设置移动平均线斜率峰值数据: {self.stock_name}")
        self.moving_average_slope_peaks_manager.update_moving_average_slope_peaks(config.DEFAULT_MA_SLOPE_PEAKS_PERIODS, config.MA_SLOPE_PEAKS_COLORS)
        logger.debug(f"更新移动平均线斜率峰值数据: {self.stock_name}")
        
        # 设置价格和成交量范围
        self._set_ranges()
        
        # 设置X轴范围和日期刻度
        self._set_axes()
    
    def _set_ranges(self):
        """设置图表范围"""
        min_price, max_price = self.data_loader.get_price_range()
        min_volume, max_volume = self.data_loader.get_volume_range()

        # K线图价格范围
        self.kline_chart.set_price_range(min_price, max_price)

        # 移动平均线范围
        self.moving_average_manager.set_price_range(min_price, max_price)

        # 移动平均线斜率峰值范围
        self.moving_average_slope_peaks_manager.set_price_range(min_price, max_price)
        logger.debug(f"设置移动平均线斜率峰值范围: {self.stock_name}")

        # 成交量范围
        self.volume_chart.set_volume_range(min_volume, max_volume)
        # 将成交量按价格比例缩放
        self.volume_chart.scale_volume_to_price(max_volume, max_price)
    
    def _set_axes(self):
        """设置坐标轴"""
        data_length = len(self.data_loader.get_data())
        # 设置日期刻度
        date_ticks = self.data_loader.get_date_ticks(config.MAX_DATE_TICKS)
        
        # 设置X轴范围
        self.kline_chart.set_x_range(0, data_length - 1)
        self.kline_chart.set_date_ticks(date_ticks)
    
        # 设置X轴范围
        self.moving_average_manager.set_x_range(0, data_length - 1)
        self.moving_average_manager.set_date_ticks(date_ticks)

        # 移动平均线斜率峰值范围
        self.moving_average_slope_peaks_manager.set_x_range(0, data_length - 1)
        self.moving_average_slope_peaks_manager.set_date_ticks(date_ticks)
        logger.debug(f"设置移动平均线斜率峰值范围: {self.stock_name}")

        self.volume_chart.set_x_range(0, data_length - 1)
        self.volume_chart.set_date_ticks(date_ticks)
            
    
    def _setup_mouse_interactions(self):
        """设置鼠标交互"""
        # K线图鼠标交互
        kline_interaction = MouseInteraction(
            self.kline_plot, 
            self.data_loader, 
            "kline"
        )
        self.mouse_manager.add_interaction(kline_interaction)
        
        # 成交量图鼠标交互
        volume_interaction = MouseInteraction(
            self.volume_plot, 
            self.data_loader, 
            "volume"
        )
        self.mouse_manager.add_interaction(volume_interaction)
    
    def cleanup(self):
        """清理资源"""
        self.mouse_manager.disconnect_all()


class MultiStockWindow(QWidget):
    """多股票图表窗口"""
    
    def __init__(self, stocks_info: List[Dict[str, str]]):
        """
        初始化多股票窗口
        
        Args:
            stocks_info: 股票信息列表，格式为 [{"name": "股票名", "path": "文件路径"}, ...]
        """
        super().__init__()
        self.stocks_info = stocks_info
        self.stock_widgets: List[SingleStockWidget] = []
        
        self._setup_ui()
        self._load_stocks()
    
    def _setup_ui(self):
        """设置UI"""
        self.setWindowTitle(config.DEFAULT_WINDOW_TITLE)
        self.resize(config.DEFAULT_WINDOW_WIDTH, config.DEFAULT_WINDOW_HEIGHT)
        
        layout = QVBoxLayout()
        self.setLayout(layout)
        
        # 创建标签页控件
        self.tab_widget = QTabWidget()
        layout.addWidget(self.tab_widget)
    
    def _load_stocks(self):
        """加载股票数据"""
        for stock_info in self.stocks_info:
            try:
                stock_widget = SingleStockWidget(
                    stock_info["name"], 
                    stock_info["path"]
                )
                
                self.stock_widgets.append(stock_widget)
                self.tab_widget.addTab(stock_widget, stock_info["name"])
                
                print(f"已加载 {stock_info['name']} 数据")
                
            except Exception as e:
                print(f"加载 {stock_info['name']} 失败: {e}")
    
    def cleanup(self):
        """清理所有资源"""
        for widget in self.stock_widgets:
            widget.cleanup()


class MultiWindowManager:
    """多窗口管理器"""
    
    def __init__(self):
        self.app: Optional[QApplication] = None
        self.main_window: Optional[MultiStockWindow] = None
    
    def create_app(self):
        """创建QApplication实例"""
        if self.app is None:
            self.app = QApplication(sys.argv)
    
    def create_multi_stock_window(self, stocks_info: List[Dict[str, str]]) -> MultiStockWindow:
        """
        创建多股票窗口
        
        Args:
            stocks_info: 股票信息列表
            
        Returns:
            多股票窗口实例
        """
        if self.app is None:
            self.create_app()
        
        self.main_window = MultiStockWindow(stocks_info)
        return self.main_window
    
    def run(self):
        """运行应用程序"""
        if self.app is None:
            raise ValueError("应用程序尚未创建")
        
        sys.exit(self.app.exec_())
    
    def cleanup(self):
        """清理资源"""
        if self.main_window:
            self.main_window.cleanup()


def run_multi_stock_charts(stocks_info: List[Dict[str, str]]):
    """
    运行多股票图表的便捷函数
    
    Args:
        stocks_info: 股票信息列表，格式为 [{"name": "股票名", "path": "文件路径"}, ...]
    """
    manager = MultiWindowManager()
    
    try:
        # 创建多股票窗口
        window = manager.create_multi_stock_window(stocks_info)
        window.show()
        
        # 运行应用程序
        manager.run()
        
    finally:
        manager.cleanup()
